/*******************************************************************************
 * ChilliWindow.cpp
 *
 * Copyright (c) 2013, Varuna L Amachi. All rights reserved.
 *
 * This program/library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This program/library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 ******************************************************************************/

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <core/manager/T.h>
#include <core/workers/DbCommandHandler.h>
#include <QMouseEvent>
#include <QDesktopWidget>
#include <QSizeGrip>
#include <QMargins>

#include "ChilliWindow.h"
#include "ComponentManager.h"
#include "player/AudioPlayerWidget.h"
#include "player/PlaylistWidget.h"
#include "common/DbTempDataCleaner.h"
#include "common/ChilliCache.h"


using namespace GreenChilli;

static void delay()
{
    QTime dieTime= QTime::currentTime().addSecs(1);
    while( QTime::currentTime() < dieTime )
    QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}



ChilliWindow::ChilliWindow(QWidget *parent) :
    QMainWindow(parent),
    m_maximizeIcon( new QIcon( ":/images/addfolder_act" )),
    m_restoreIcon( new QIcon( ":/images/addfiles_act" )),
    m_maximised( false )
{
    PLAYLIST()->addItems( DATA_RETRIEVER()->getSavedCurrentPlaylist() );
    setWindowFlags( Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint );
    new DbTempDataCleaner( this );
    QWidget *central  = new QWidget( this );
    this->setContentsMargins( 1, 1, 1, 1 );

    QVBoxLayout *playerLayout = new QVBoxLayout();
    m_audioPlayer = new AudioPlayerWidget( this );
    m_playlist = new PlaylistWidget( this );
    playerLayout->addWidget( m_audioPlayer );
    playerLayout->addWidget( m_playlist );



    QHBoxLayout *mainLayout = new QHBoxLayout();

    QWidget *titleWidget = new QWidget( this );
    titleWidget->setStyleSheet(
                "background-color: qlineargradient( x1:0 y1:0, "
                "x2:0 y2:1, stop:0 #3C444C, stop:1 #151515);" );
    QPushButton *closeButton = new QPushButton(
                QIcon( ":/images/clear_act" ),
                "",
                this );
    closeButton->setFlat( true );
    closeButton->setFixedSize( QSize( 16, 16 ));
    closeButton->setToolTip( tr( "Exit" ));

    QPushButton *minimizeButton = new QPushButton(
                QIcon( ":/images/remove_act" ),
                "",
                this );
    minimizeButton->setFlat( true );
    minimizeButton->setFixedSize( QSize( 16, 16 ));
    minimizeButton->setToolTip( tr( "Exit" ));

    m_maxRestore = new QPushButton(
                    *m_maximizeIcon,
                    "",
                    this );
    m_maxRestore->setFlat( true );
    m_maxRestore->setFixedSize( QSize( 16, 16 ));
    m_maxRestore->setToolTip( tr( "Exit" ));

    QVBoxLayout *titleLayout = new QVBoxLayout();
    titleLayout->setDirection( QBoxLayout::RightToLeft );
    titleLayout->addWidget( closeButton );
    titleLayout->addWidget( m_maxRestore );
    titleLayout->addWidget( minimizeButton );
    titleLayout->addStretch();

    titleWidget->setLayout( titleLayout );
    titleWidget->setFixedHeight( 20 );
    titleLayout->setContentsMargins( 0, 2, 2, 0 );
    minimizeButton->setContentsMargins( 0, 0, 0, 0 );
    closeButton->setContentsMargins( 0, 0, 0, 0 );

    QHBoxLayout *compLayout = new QHBoxLayout();
    compLayout->addWidget( ComponentManager::get() );
    QSizeGrip *sizeGrip = new QSizeGrip( this );
    sizeGrip->setFixedSize( 6, 6 );
    sizeGrip->setStyleSheet( "background-color: red;");
    sizeGrip->setToolTip( tr( "Drag to resize the window" ));
    compLayout->addWidget( sizeGrip,
                           0,
                           Qt::AlignBottom | Qt::AlignRight );
    sizeGrip->setContentsMargins( QMargins() );
    compLayout->setContentsMargins( QMargins() );
    compLayout->setSpacing( 0 );


    QVBoxLayout *leftLayout = new QVBoxLayout();
    leftLayout->addWidget( titleWidget );
    leftLayout->addLayout( compLayout );

    leftLayout->setContentsMargins( QMargins() );
    leftLayout->setSpacing( 0 );
    m_leftWidget = new QWidget( this );
    m_leftWidget->setLayout( leftLayout );
    m_leftWidget->setContentsMargins( QMargins() );

    mainLayout->addLayout( playerLayout );
    mainLayout->addWidget( m_leftWidget );
    mainLayout->setContentsMargins( QMargins() );
    mainLayout->setSpacing( 0 );

    QPalette pal = central->palette();
    central->setAutoFillBackground( true );
    pal.setBrush( QPalette::Window, QColor( Qt::black ));
    central->setPalette( pal );
    QString css = createStyleSheet();

    ComponentManager::get()->setStyleSheet( css );
    m_playlist->setStyleSheet( css );
    playerLayout->setContentsMargins( QMargins() );
    playerLayout->setSpacing( 0 );

    connect( m_audioPlayer, SIGNAL( urlsDropped( QList< QUrl > )),
             m_playlist, SLOT( addUrls( QList< QUrl > )));
    connect( m_audioPlayer, SIGNAL( playFromPlaylist() ),
             m_playlist, SLOT( setSelectedAsCurrent() ));
    connect( QCoreApplication::instance(),
             SIGNAL( aboutToQuit() ),
             this,
             SLOT( onAboutToQuit() ));
    connect( closeButton, SIGNAL( released() ),
             QApplication::instance(), SLOT( quit() ));
    connect( minimizeButton, SIGNAL( released() ),
             this, SLOT( onMinimize() ));
    connect( m_maxRestore, SIGNAL( released() ),
             this, SLOT( onMaximizeRestore() ));
    central->setLayout( mainLayout );
    this->setCentralWidget( central );
}



void ChilliWindow::onAboutToQuit()
{
    while( DBCMD_HANDLER()->hasPendingTasks() ) {
        delay();
    }
    const QList< Tanyatu::Model::MediaItem *> *list =
            PLAYLIST()->getAllItemsInOrder();
    DATA_UPDATER()->saveCurrentPlaylist( *list );
    ComponentManager::destroy();
    CHILLI_CACHE()->destroy();
}


void ChilliWindow::mousePressEvent( QMouseEvent* event )
{
    if( event->button() == Qt::LeftButton ) {
        m_moving = true;
        m_lastMousePosition = event->globalPos();
    }
}

void ChilliWindow::mouseMoveEvent( QMouseEvent* event )
{
    if( event->buttons().testFlag( Qt::LeftButton ) && m_moving ) {
        QPoint newPos = this->pos() + (
                    event->globalPos() - m_lastMousePosition );
        if( newPos.y() <= 0 ) {
            m_maximised = true;
//            showMaximized();
            maximize();
        }
        else if( m_maximised && newPos.y() >= 10 ) {
            m_maximised = false;
            restore();
            move( event->globalX() - this->width() / 2, event->globalY() );
        }
        else {
            move( newPos );
        }
        m_lastMousePosition = event->globalPos();
    }
}

void ChilliWindow::mouseReleaseEvent( QMouseEvent* event )
{
    if( event->button() == Qt::LeftButton )
    {
        m_moving = false;
    }
}

void ChilliWindow::showEvent( QShowEvent *evt )
{
    if( m_geometry.isEmpty() ) {
        m_geometry = this->saveGeometry();
    }
    QMainWindow::showEvent( evt );
}


void ChilliWindow::maximize()
{
    QDesktopWidget *desktop = QApplication::desktop();
    // Because reserved space can be on all sides of the scren
    // you have to both move and resize the window
    this->setGeometry( desktop->availableGeometry() );
}


void ChilliWindow::restore()
{
    if( ! m_geometry.isEmpty() ) {
        this->restoreGeometry( m_geometry );
    }
}


void ChilliWindow::minimize()
{
    if( ! this->isMinimized() ) {
        this->showMinimized();
    }
}

QString ChilliWindow::createStyleSheet()
{
    return "QWidget{"
            "background-color: black; "
            "color: #FFA858;"
            "border-color: black;"
        "}"
        "QPushButton{"
            "background-color: #202020; "
            "color: #FFA858;"
            "border-width: 8px;"
            "border-color: black;"
        "}"
        "QTreeView{ "
            "background-color: #151515;"
            "alternate-background-color: #202020;"
        "}"
        "QTreeView::item:selected:active, QTreeView::item:selected:!active,"
        "QListView::item:selected:active, QListView::item:selected:!active{"
            "color: #151515; "
            "background-color: rgba( 255, 168, 48, 200 );"
        "}"
        "QHeaderView::section {"
            "background-color: #202020;"
            "color: white;"
        "}"
        "QTreeView::item:hover, QListView::item:hover { "
            "background-color: rgba( 255, 168, 48, 130 );"
        "}"
        "QProgressBar{ "
            "border-radius: 5px;"
            "color: white;"
            "text-align: center;"
        "}"
        "QProgressBar::chunk {"
            "background-color: #FFA858;"
        "}"
        "QLineEdit{ background-color: #444444;}"
        "QMenu{ background-color: #444444;}"
        "QMenu::item:selected{background-color: #696969; }";
}


void ChilliWindow::onMinimize()
{
    showMinimized();
}

//void ChilliWindow::onChilliClick()
//{
//    if( m_uiState == Ui_Full ) {
//        m_uiState = Ui_PlayerPlaylist;
//        if( m_maximised ) {
//            onMaximizeRestore();
//        }
//        this->resize( m_audioPlayer->width(), this->height() );
//        m_leftWidget->hide();
//    }
//    else if( m_uiState == Ui_PlayerPlaylist ) {
//        m_uiState = Ui_Player;
//        this->setFixedWidth( AudioPlayerWidget::AUDIO_PLAYER_WIDTH );
//        m_playlist->hide();
//    }
//    else {
//        m_uiState = Ui_Full;
//        this->setFixedSize( AudioPlayerWidget::AUDIO_PLAYER_WIDTH,
//                            AudioPlayerWidget::AUDIO_PLAYER_HEIGHT );
//        m_leftWidget->setVisible( true );
//        m_playlist->setVisible( true );
//        onMaximizeRestore();

//    }
//}

void ChilliWindow::onMaximizeRestore()
{
    if( m_maximised ) {
        m_maxRestore->setIcon( *m_maximizeIcon );
        m_maximised = false;
        restore();
    }
    else {
        m_geometry = saveGeometry();
        m_maximised = true;
        m_maxRestore->setIcon( *m_restoreIcon );
        maximize();
    }
}




